﻿/*
 * 框架库主程序
 * 对外暴露静态扩展方法注入 MauiAppBuilder
 * 使用方法：
 *      MauiAppBuilder builder = MauiApp.CreateBuilder();
 *       builder.UseElio();
 *      ...
 *      同时需要把ServiceProvider传递到ElioLib
        MauiApp app = builder.Build();
        ElioLibProgram.Services = app.Services;
        return app;
 * 然后在主程序页面中就可以导入ElegantPage页面（需要引入命名空间using Elio.Views）
 */

using CommunityToolkit.Maui;
using Io.Elegant;
using Elio.Sessions;
using Elio.Sessions.Media;
using Elio.Sessions.Widgets;
using Elio.Widgets;
using Elio.ViewModels;
using Elio.Views;

namespace Elio;

public static class ElioLibProgram
{
    // ReSharper disable once UnusedAutoPropertyAccessor.Global
    public static IServiceProvider? Services { get; set; }

    public static MauiAppBuilder UseElio(this MauiAppBuilder builder)
    {
        builder
            .RegisterGrpc()
            .RegisterServices()
            .RegisterViews()
            .RegisterControls()
            .RegisterViewModels()
            .UseMauiCommunityToolkit()
            .UseMauiCommunityToolkitMediaElement();

        return builder;
    }

    private static MauiAppBuilder RegisterGrpc(this MauiAppBuilder builder)
    {
        string clientId = Utils.GetClientId();
        string platform = Utils.GetPlatform();
        string localhost = Utils.GetIpAddress();
        // TODO  安卓端未获取到本地IP,而是127.0.0.1 无法运行
        localhost = "192.168.0.108";
        localhost = "192.168.118.203";

        builder
            .Services
            .AddGrpcClient<ElegantApi.ElegantApiClient>(o =>
            {
                o.Address = new Uri($"http://{localhost}:8000");
            })
            .ConfigureChannel(o =>
            {
                // 启用不安全传输，在没有TSL的情况下才可以传输元数据
                o.UnsafeUseInsecureChannelCallCredentials = true;
                o.MaxReceiveMessageSize = 10 * 1024 * 1024; // 10MB
                o.MaxSendMessageSize = 10 * 1024 * 1024; // 10MB
                o.MaxRetryAttempts = 3;
                o.MaxRetryBufferSize = 2 * 1024 * 1024; // 2MB
            })
            .AddCallCredentials((_, metadata) =>
            {
                metadata.Add("client-id", clientId);
                metadata.Add("platform", $"MAUI-{platform}");
                return Task.CompletedTask;
            });

        return builder;
    }

    private static MauiAppBuilder RegisterServices(this MauiAppBuilder builder)
    {
        builder
            .Services
            .AddTransient<ActivitySession>()
            .AddTransient<TextToSpeechSession>()
            .AddTransient<MediaPlayerSession>()
            .AddTransient<MediaRecorderSession>()
            .AddTransient<AudioTrackSession>()
            .AddTransient<WidgetTextSession>()
            .AddTransient<WidgetButtonSession>()
            .AddTransient<WidgetEditorSession>()
            .AddTransient<WidgetCheckBoxSession>()
            .AddTransient<WidgetImageSession>()
            .AddTransient<WidgetProgressBarSession>()
            .AddTransient<WidgetRadioSession>()
            .AddTransient<WidgetSpinnerSession>()
            .AddTransient<WidgetFileUploaderSession>()
            .AddTransient<GenericDialogSession>()
            .AddTransient<SoundPoolSession>()
            .AddTransient<RequestsSession>()
            .AddTransient<SensorSession>()
            .AddTransient<FileSession>();

        return builder;
    }

    private static MauiAppBuilder RegisterViews(this MauiAppBuilder builder)
    {
        builder
            .Services
            .AddTransient<ElegantPage>();

        return builder;
    }
    private static MauiAppBuilder RegisterControls(this MauiAppBuilder builder)
    {
        builder
            .Services
            .AddTransient<WidgetButton>()
            .AddTransient<WidgetCheckBox>()
            .AddTransient<WidgetEditor>()
            .AddTransient<WidgetFileUploader>()
            .AddTransient<WidgetImage>()
            .AddTransient<WidgetProgressBar>()
            .AddTransient<WidgetRadio>()
            .AddTransient<WidgetSpinner>()
            .AddTransient<WidgetText>();

        return builder;
    }

    private static MauiAppBuilder RegisterViewModels(this MauiAppBuilder builder)
    {
        builder
            .Services
            .AddTransient<ElegantPageViewModel>();

        return builder;
    }
}
